#pragma once
#include <stdio.h>
#include <iostream>
#include <conio.h>              //For easier console output manipulation ~Garth
#include <Windows.h>			//Same ~Garth
#include "map.h"
#include "random.h"

//Defined ID's of all of the shapes
#define SQUARE 0
#define LINE 1
#define TSHAPE 2
#define RIGHTL 3
#define LEFTL 4
#define SSHAPE 5
#define ZSHAPE 6

//defined ID's of all position that a shape could be in
#define POS1 0 //starting
#define POS2 1  //clockwise
#define POS3 2  //...
#define POS4 3  //......

//dimensions for map
#define HEIGHT 14
#define WIDTH 10
//dimensions for "next" map
#define BOX_HEIGHT 6
#define BOX_WIDTH  9

//need some colors to manipulate ~andy
#define BASE_COLOR (FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE)
#define BLUE_COLOR (FOREGROUND_BLUE|FOREGROUND_INTENSITY)
#define RED_COLOR  (FOREGROUND_RED|FOREGROUND_INTENSITY)
#define GREEN_COLOR (FOREGROUND_GREEN|FOREGROUND_INTENSITY)
#define YELLOW_COLOR (FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_INTENSITY)
#define PURPLE_COLOR (FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_INTENSITY)
#define TEAL_COLOR	(FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY)
#define BROWN_COLOR (FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_INTENSITY)

#define DIFFICULTY_RAMP_UP 100  //#define for what the player score must be a multiple of for the difficulty to increase. ~Garth

using namespace std;


tetrisMap::tetrisMap(int a_hposition)
{
	firstTime = true;
	hitBottom = true;
	singleDown = false;
	//initialize everything
	int color = BASE_COLOR;
	m_curShapePos = POS1;
	//first shape is always a square... we should prolly change this ~Andy
	m_nextShapeID = (random() % 7);
	m_height = HEIGHT;
	m_width = WIDTH;
	m_boxHeight = BOX_HEIGHT;
	m_boxWidth = BOX_WIDTH;
	m_hposition = a_hposition;
	m_mapArray = new bool*[m_height];
	m_nextArray = new bool*[m_boxHeight];
	m_staticArray = new bool*[m_height];
	m_pieceArray = new bool*[m_height];
	//array for colors
	m_colorArray = new int*[m_height];
	m_playerScore = 0; //Initialize the player's score ~Garth
	m_difficultyLevel = 0;  //Initialize the difficulty level ~Garth

	//init the dynamic 2D array
	for(int i = 0; i <= m_height; ++i)
	{
		m_pieceArray[i] = new bool [m_width];
		m_staticArray[i] = new bool[m_width];
		m_nextArray[i] = new bool[m_width];
		m_mapArray[i] = new bool[m_width];
		//array for colors
		m_colorArray[i] = new int[m_width];
	}

	//set values for the array to false (guess i dont need to tho)
	for(int i = 0; i <= m_height; ++i)
	{
		for(int i2 = 0; i2 <= m_width; ++i2)
		{
			m_mapArray[i][i2] = false;
			m_nextArray[i][i2] = false;
			m_staticArray[i][i2] = false;
			m_pieceArray[i][i2] = false;
			//init the color array
			m_colorArray[i][i2] = BASE_COLOR;
		}
	}
}
void tetrisMap::displayMap()
{
	//int color;
	//display the map
			int eye[4];
		int eye2[4];
		int count = 0;
		while(count <= 3)
		{
			eye[count] = 0;
			eye2[count] = 0;
			count++;
		}
		count = 0;
		for(int i = 0; i <= m_height; ++i)
		{
			for(int i2 = 0; i2 <= m_width; ++i2)
			{
				if(m_mapArray[i][i2])
				{
					if(count <= 3)
					{
						eye[count] = i;
						eye2[count] = i2;
						++count;
					}
				}
			}
		}	
		count = 0;
	for(int i = 0; i <= m_height; ++i)
	{
		for(int i2 = 0; i2 <= m_width; ++i2)
		{
			COORD drawto = {m_hposition + i2, i + 1};									//Where to put on screen
			SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), drawto);	//Same ~Garth
			SetConsoleTextAttribute(
				GetStdHandle(STD_OUTPUT_HANDLE),
				m_colorArray[i][i2]);		
			//if static (already dropped), draw this
			if(m_staticArray[i][i2])
			{
				printf("#");
			}
			//if it is an active piece dropping, draw this
			else if(m_mapArray[i][i2])
			{
				printf("*");
			}
			//otherwise draw the dot, if it is an empty space on the map
			else
			{
				SetConsoleTextAttribute(
					GetStdHandle(STD_OUTPUT_HANDLE),
					BASE_COLOR);
				printf(".");
			}
		}
		//newline after each row
		printf("\n");
	}
	drawProjected(eye, eye2);
	SetConsoleTextAttribute(
		GetStdHandle(STD_OUTPUT_HANDLE),
		BASE_COLOR);
}
void tetrisMap::displayNextMap()
{
	//int color;
	//display the "next" map
	COORD drawto = {m_hposition, m_height + 2};
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), drawto);
	printf("___________\n");
	printf("Next:  \n");
	for(int i = 0; i <= m_boxHeight; ++i)
	{
		
		for(int i2 = 0; i2 <= m_boxWidth; ++i2)
		{
			drawto.X = m_hposition + i2;
			drawto.Y = i + m_height + 4;
			SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), drawto);
			// draw the next piece using this
			if (m_nextArray[i][i2])
			{
				printf("#");
			}
			//otherwise draw an empty space
			else
			{
				SetConsoleTextAttribute(
					GetStdHandle(STD_OUTPUT_HANDLE),
					BASE_COLOR);
				printf(" ");
			}
		}
		//newline after each row
		printf("\n");
	}
	SetConsoleTextAttribute(
		GetStdHandle(STD_OUTPUT_HANDLE),
		BASE_COLOR);
}
void tetrisMap::flipShape()
{
	//notDone is used when collision is found, if it is found it stops trying to rotate and says, "i am done trying to flip this shape"
	notDone = true;
	//not sure if we need these here
	int i = 0; int i2 = 0;
	//the following is all of the flipping code, which checks for collision on a flip for every position possible for that shape
	switch(m_curShapeID)
	{
	case SQUARE:
		//ITS A SQUARE DUMMY DONT FLIP IT LOL
		break;
	case LINE: //STRAIGHT LINE!
		switch(m_curShapePos)
		{
		case POS1:
			rotateLineToHorizontalPosition();
			break;
		case POS2:
			rotateLineToVerticalPosition();
			break;
		}
		break;
	case TSHAPE: //T-SHAPE
		switch(m_curShapePos)
		{
		case POS1:
			rotateTshapeFirstClockwisePosition();
			break;
		case POS2:
			rotateTshapeSecondClockwisePosition();
			break;
		case POS3:
			rotateTshapeThirdClockwisePosition();
			break;
		case POS4:
			rotateTshapeFourthClockwisePosition();
			break;
		}
		break;
	case RIGHTL:
		switch(m_curShapePos)
		{
		case POS1:
			rotateRightLShapeClockwiseFirstPosition();
			break;
		case POS2:
			rotateRightLShapeClockwiseSecondPosition();
			break;
		case POS3:
			rotateRightLShapeClockwiseThirdPosition();
			break;
		case POS4:
			rotateRightLShapeClockwiseFourthPosition();
			break;
		}
		break;
	case LEFTL:
		switch(m_curShapePos)
		{
		case POS1:
			rotateLeftLShapeClockwiseFirstPosition();
			break;
		case POS2:
			rotateLeftLShapeClockwiseSecondPosition();
			break;
		case POS3:
			rotateLeftLShapeClockwiseThirdPosition();
			break;
		case POS4:
			rotateLeftLShapeClockwiseFourthPosition();
			break;
		}
		break;
	case SSHAPE:
		switch(m_curShapePos)
		{
		case POS1:
			rotateSShapeToHorizontalPosition();
			break;
		case POS2:
			rotateSShapeToVerticalPosition();
			break;
		}
		break;
	case ZSHAPE:
		switch(m_curShapePos)
		{
		case POS1:
			rotateZShapeToHorizontalPosition();
			break;
		case POS2:
			rotateZShapeToVerticalPosition();
			break;
		}
		break;
	}
}

void tetrisMap::createPiece()
{
	//assign the previous "next piece" as current
	m_curShapeID = m_nextShapeID;
	//decide what the next piece will be
	m_nextShapeID = (random() % 7);
	//sets array for next piece
	setNextPiece(m_nextShapeID);
	//based on the ID draw that shape in its position
	switch(m_curShapeID)
	{
	case 0: //square
		createSquare();
		break;
	case 1: //straight line
		createStraightLine();
		break;
	case 2: //T-SHAPE
		createTShape();
		break;
	case 3: //right L
		createRightLShape();
		break;
	case 4: //left L
		createLeftLShape();
		break;
	case 5: //SShape
		createSShape();
		break;
	case 6: //ZShape
		createZShape();
		break;
	}
}

void tetrisMap::setNextPiece(int m_nextShapeID)
{
	switch(m_nextShapeID)
	{
	case 0:
		setNextSquarePiece();
		break;
	case 1: //straight line
		setNextStraightLinePiece();
		break;
	case 2: //T-SHAPE
		setNextTShapePiece();
		break;
	case 3: //right L
		setNextRightLShapePiece();
		break;
	case 4: //left L
		setNextLeftLShapePiece();
		break;
	case 5: //SShape
		setNextSShapePiece();
		break;
	case 6: //ZShape
		setNextZShapePiece();
		break;
	}
}
void tetrisMap::lineCheck()
{
	//check each row for a line from top to bottom
	for(int i = 0; i <= m_height; ++i)
	{
		if(m_staticArray[i][0] &&
			m_staticArray[i][1] &&
			m_staticArray[i][2] &&
			m_staticArray[i][3] &&
			m_staticArray[i][4] &&
			m_staticArray[i][5] &&
			m_staticArray[i][6] &&
			m_staticArray[i][7] &&
			m_staticArray[i][8] &&
			m_staticArray[i][9] &&
			m_staticArray[i][10])
		{
			/* Score Code ~Garth*/
			m_playerScore += 10;							//Found a full line, so add ten to score
			if (m_playerScore % DIFFICULTY_RAMP_UP == 0)    //If the player has reached a new difficulty threshold
			{
				m_difficultyLevel++;                       //Increase the difficulty
			}
			//These three lines print it out
			COORD scoreline = {m_hposition, 0};                                                                       
			SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), scoreline);
			printf("Score:  %d.  Level:  %d.", m_playerScore, m_difficultyLevel);
			//if it is a straight line then set that static array back to false (destroy the line)
			for(int i2 = 0; i2 <= m_width; ++i2)
			{
				m_staticArray[i][i2] = false;

			}
			while(i > 0)
			{
				//then we shift everything down, which sets i back to the top and we do it all over again until no lines are found
				--i;
				for(int i2 = 0; i2 <= m_width; ++i2)
				{
					if(m_staticArray[i][i2])
					{
						m_staticArray[i+1][i2] = true;
						m_staticArray[i][i2] = false;
						//shift the colors down as well
						m_colorArray[i+1][i2] = m_colorArray[i][i2];
						m_colorArray[i][i2] = BASE_COLOR;
					}
				}
			}
		}
	}
}
void tetrisMap::addToStatic()
{
	//add a piece to the static array based on its current position in the mapArray 
	//(this is called when collision is found in the downshift)

	for(int i = 0; i <= m_height; ++i)
	{
		for(int i2 = 0; i2 <= m_width; ++i2)
		{
			if(m_mapArray[i][i2])
			{
				m_staticArray[i][i2] = true;
			}
		}
	}
	//after collision is found and the shape is added to the static array, we check the static array for lines
	lineCheck();
}

void tetrisMap::downShift()
{
	//check to see if we can move down, do this by checking every active true against static and height, etc
	bool canMove = false;
	//do collision detection here!
	for(int i = 0; i <= m_height; ++i)
	{
		for(int i2 = 0; i2 <= m_width; ++i2)
		{
			if((m_mapArray[i][i2]) && (i == (m_height)))
			{
				addToStatic();
				clearMap();
				createPiece();
			}
			else if(m_mapArray[i][i2] && m_staticArray[i+1][i2])
			{
				addToStatic();
				clearMap();
				createPiece();
			}
			else
			{
				canMove = true;
			}
		}
	}
	//if we can move down we do it, but we do it from the bottom up to prevent overlapping a shape
	if(canMove)
	{
		for(int i = m_height; i >= 0; --i)
		{
			for(int i2 = 0; i2 <= m_width; ++i2)
			{
				if(m_mapArray[i][i2])
				{
					m_mapArray[i+1][i2] = true;
					m_mapArray[i][i2] = false;
					//move the colors down with the shape
					m_colorArray[i+1][i2] = m_colorArray[i][i2];
					m_colorArray[i][i2] = BASE_COLOR;
				}
			}
		}

	}
}

void tetrisMap::rightShift()
{
	//shift right, first make sure we are able to
	bool canMove = true;

	for(int i = 0; i <= m_height; ++i)
	{
		for(int i2 = 0; i2 <= m_width; ++i2)
		{
			if(m_mapArray[i][i2] && i2 == m_width || m_mapArray[i][i2] && m_staticArray[i][i2+1])
			{
				canMove = false;
			}
		}
	}
	//if we are able to then we shift right, from right to left to prevent overlapping
	if(canMove)
	{
		for(int i = 0; i <= m_height; ++i)
		{
			for(int i2 = m_width; i2 >= 0; --i2)
			{
				if(m_mapArray[i][i2] && i2 < m_width)
				{
					m_mapArray[i][i2+1] = true;
					m_mapArray[i][i2] = false;
					//shift the colors to the right
					m_colorArray[i][i2+1] = m_colorArray[i][i2];
					m_colorArray[i][i2] = BASE_COLOR;
				}
			}
		}
	}
}

void tetrisMap::leftShift()
{
	//shift left
	bool canMove = true;
	//check to see if we are able to shift left
	for(int i = 0; i <= m_height; ++i)
	{
		for(int i2 = 0; i2 <= m_width; ++i2)
		{
			if(m_mapArray[i][i2] && i2 == 0 || m_mapArray[i][i2] && m_staticArray[i][i2-1])
			{
				canMove = false;
			}
		}
	}

	//if we are allowed then we shift left, from left to right to prevent overlapping
	if(canMove)
	{
		for(int i = 0; i <= m_height; ++i)
		{
			for(int i2 = 0; i2 <= m_width; ++i2)
			{
				if(m_mapArray[i][i2] && i2 > 0)
				{
					m_mapArray[i][i2-1] = true;
					m_mapArray[i][i2] = false;
					//shift the colors to the left
					m_colorArray[i][i2-1] = m_colorArray[i][i2];
					m_colorArray[i][i2] = BASE_COLOR;
				}
			}
		}
	}
}
void tetrisMap::clearMap()
{
	//clear the active map (once the shape is added to static
	for(int i = 0; i <= m_height; ++i)
	{
		for(int i2 = 0; i2 <= m_width; ++i2)
		{
			m_mapArray[i][i2] = false;
			m_nextArray[i][i2] = false;
		}
	}
}

bool tetrisMap::checkLoss()
{
	//if piece makes it to top row you lose
	for(int i = 0; i <= m_width; ++i)
	{
		if(m_staticArray[0][i])
		{
			return true;
		}
	}
	return false;
}
void tetrisMap::clearStatic()
{
	//clear the static map, for starting a new game
	for(int i = 0; i <= m_height; ++i)
	{
		for(int i2 = 0; i2 <= m_width; ++i2)
		{
			m_staticArray[i][i2] = false;
			m_colorArray[i][i2] = BASE_COLOR;
		}
	}
}

void tetrisMap::rotateLineToHorizontalPosition()
{
	for(int i = 0; i <= m_height; ++i)
	{
		for(int i2 = 0; i2 <= m_width; ++i2)
		{
			if(m_mapArray[i][i2] && notDone && i2 > 0 && i2+2 <= m_width && 
				!m_staticArray[i][i2+1] && !m_staticArray[i][i2+2] && !m_staticArray[i][i2-1])
			{
				m_mapArray[i][i2] = false;              m_mapArray[i+1][i2] = false; 
				m_mapArray[i+2][i2] = false;			m_mapArray[i+3][i2] = false;
				m_mapArray[i][i2] = true;               m_mapArray[i][i2+1] = true; 
				m_mapArray[i][i2-1] = true;             m_mapArray[i][i2+2] = true;
				//gotta flip the colors too...
				m_colorArray[i][i2] = BASE_COLOR;              m_colorArray[i+1][i2] = BASE_COLOR; 
				m_colorArray[i+2][i2] = BASE_COLOR;			m_colorArray[i+3][i2] = BASE_COLOR;
				m_colorArray[i][i2] = BLUE_COLOR;               m_colorArray[i][i2+1] = BLUE_COLOR; 
				m_colorArray[i][i2-1] = BLUE_COLOR;             m_colorArray[i][i2+2] = BLUE_COLOR;

				m_curShapePos = POS2;
				notDone = false;
			}
		}
	}
}

void tetrisMap::rotateLineToVerticalPosition()
{
	for(int i = 0; i <= m_height; ++i)
	{
		for(int i2 = 0; i2 <= m_width; ++i2)
		{
			if(m_mapArray[i][i2] && notDone && i2 >= 0 && (i+3) <= m_height) //make sure you dont shift below the bottom line!
			{
				if(!m_staticArray[i+1][i2+1] &&
					!m_staticArray[i+2][i2+1] && !m_staticArray[i+3][i2+1] && !m_staticArray[i+1][i2+1] && !m_staticArray[i][i2+1])
				{       
					m_mapArray[i][i2] = false;              m_mapArray[i][i2+1] = false; 
					m_mapArray[i][i2+2] = false;    m_mapArray[i][i2+3] = false;
					m_mapArray[i+3][i2+1] = true;           m_mapArray[i][i2+1] = true;
					m_mapArray[i+1][i2+1] = true;           m_mapArray[i+2][i2+1] = true;
					//gotta flip the colors too
					m_colorArray[i][i2] = BASE_COLOR;              m_colorArray[i][i2+1] = BASE_COLOR; 
					m_colorArray[i][i2+2] = BASE_COLOR;    m_colorArray[i][i2+3] = BASE_COLOR;
					m_colorArray[i+3][i2+1] = BLUE_COLOR;           m_colorArray[i][i2+1] = BLUE_COLOR;
					m_colorArray[i+1][i2+1] = BLUE_COLOR;           m_colorArray[i+2][i2+1] = BLUE_COLOR;
					m_curShapePos = POS1;
					notDone = false;
				}else{notDone = false;} //if its the first true block and it will hit static array dont let it!
			}
		}                       
	}
}

void tetrisMap::rotateTshapeFirstClockwisePosition()
{
	for(int i = 0; i <= m_height; ++i)
	{
		for(int i2 = 0; i2 <= m_width; ++i2)
		{
			if(m_mapArray[i][i2] && notDone)
			{
				if(i+2 <= m_height && !m_staticArray[i+2][i2]
				&& !m_staticArray[i+1][i2])
				{
					m_mapArray[i+1][i2-1] = false;
					m_mapArray[i+2][i2] = true;
					//change the colors
					m_colorArray[i+1][i2-1] = BASE_COLOR;
					m_colorArray[i+2][i2] = RED_COLOR;
					//color array
					notDone = false;
					m_curShapePos = POS2;
				}else{notDone = false;}
			}
		}
	}
}

void tetrisMap::rotateTshapeSecondClockwisePosition()
{
	for(int i = 0; i <= m_height; ++i)
	{
		for(int i2 = 0; i2 <= m_width; ++i2)
		{
			if(m_mapArray[i][i2] && notDone)
			{
				if(i2-1 >= 0 && !m_staticArray[i+1][i2-1])
				{
					m_mapArray[i][i2] = false;
					m_mapArray[i+1][i2-1] = true;
					//color array
					m_colorArray[i][i2] = BASE_COLOR;
					m_colorArray[i+1][i2-1] = RED_COLOR;
					notDone = false;
					m_curShapePos = POS3;
				}else{notDone = false;}
			}
		}
	}
}

void tetrisMap::rotateTshapeThirdClockwisePosition()
{
	for(int i = 0; i <= m_height; ++i)
	{
		for(int i2 = 0; i2 <= m_width; ++i2)
		{
			if(m_mapArray[i][i2] && notDone)
			{
				if(!m_staticArray[i-1][i2+1])
				{
					m_mapArray[i][i2+2] = false;
					m_mapArray[i-1][i2+1] = true;
					//color array
					m_colorArray[i][i2+2] = BASE_COLOR;
					m_colorArray[i-1][i2+1] = RED_COLOR;
					notDone = false;
					m_curShapePos = POS4;
				}else{notDone = false;}
			}
		}
	}
}

void tetrisMap::rotateTshapeFourthClockwisePosition()
{
	for(int i = 0; i <= m_height; ++i)
	{
		for(int i2 = 0; i2 <= m_width; ++i2)
		{
			if(m_mapArray[i][i2] && notDone)
			{
				if(i2+1 <= m_width && !m_staticArray[i+1][i2+1])
				{
					m_mapArray[i+2][i2] = false;
					m_mapArray[i+1][i2+1] = true;
					//color array
					m_colorArray[i+2][i2] = BASE_COLOR;
					m_colorArray[i+1][i2+1] = RED_COLOR;
					notDone = false;
					m_curShapePos = POS1;
				}else{notDone = false;}
			}
		}
	}
}

void tetrisMap::rotateRightLShapeClockwiseSecondPosition()
{
	for(int i = 0; i <= m_height; ++i)
	{
		for(int i2 = 0; i2 <= m_width; ++i2)
		{
			if(m_mapArray[i][i2] && notDone)
			{
				if(!m_staticArray[i+1][i2+1] && !m_staticArray[i-1][i2+1] && !m_staticArray[i-1][i2])
				{
					m_mapArray[i][i2] = false; m_mapArray[i+1][i2] = false; m_mapArray[i][i2+2] = false;
					m_mapArray[i-1][i2+1] = true; m_mapArray[i+1][i2+1] = true; m_mapArray[i-1][i2] = true;
					//color array
					m_colorArray[i][i2] = BASE_COLOR; m_colorArray[i+1][i2] = BASE_COLOR; m_colorArray[i][i2+2] = BASE_COLOR;
					m_colorArray[i-1][i2+1] = PURPLE_COLOR; m_colorArray[i+1][i2+1] = PURPLE_COLOR; m_colorArray[i-1][i2] = PURPLE_COLOR;
					notDone = false;
					m_curShapePos = POS3;
				}
				else{notDone = false;}
			}
		}
	}
}

void tetrisMap::rotateRightLShapeClockwiseFirstPosition()
{
	for(int i = 0; i <= m_height; ++i)
	{
		for(int i2 = 0; i2 <= m_width; ++i2)
		{
			if(m_mapArray[i][i2] && notDone)
			{
				if(i2-1 >= 0 && i2+1 <= m_width && !m_staticArray[i+1][i2+1] &&
					!m_staticArray[i+1][i2-1] && !m_staticArray[i+2][i2-1])
				{
					m_mapArray[i][i2] = false; m_mapArray[i+2][i2] = false; m_mapArray[i+2][i2+1] = false;
					m_mapArray[i+1][i2+1] = true; m_mapArray[i+1][i2-1] = true; m_mapArray[i+2][i2-1] = true;
					//color array
					m_colorArray[i][i2] = BASE_COLOR; m_colorArray[i+2][i2] = BASE_COLOR; m_colorArray[i+2][i2+1] = BASE_COLOR;
					m_colorArray[i+1][i2+1] = PURPLE_COLOR; m_colorArray[i+1][i2-1] = PURPLE_COLOR; m_colorArray[i+2][i2-1] = PURPLE_COLOR;
					notDone = false;
					m_curShapePos = POS2;
				}else{notDone = false;}
			}
		}
	}
}

void tetrisMap::rotateRightLShapeClockwiseThirdPosition()
{
	for(int i = 0; i <= m_height; ++i)
	{
		for(int i2 = 0; i2 <= m_width; ++i2)
		{
			if(m_mapArray[i][i2] && notDone)
			{
				if(i2+2 <= m_width && !m_staticArray[i][i2+2] && !m_staticArray[i+1][i2+2] && !m_staticArray[i+1][i2])
				{
					m_mapArray[i][i2] = false; m_mapArray[i][i2+1] = false; m_mapArray[i+2][i2+1] = false;
					m_mapArray[i][i2+2] = true; m_mapArray[i+1][i2+2] = true; m_mapArray[i+1][i2] = true;
					//color array
					m_colorArray[i][i2] = BASE_COLOR; m_colorArray[i][i2+1] = BASE_COLOR; m_colorArray[i+2][i2+1] = BASE_COLOR;
					m_colorArray[i][i2+2] = PURPLE_COLOR; m_colorArray[i+1][i2+2] = PURPLE_COLOR; m_colorArray[i+1][i2] = PURPLE_COLOR;
					notDone = false;
					m_curShapePos = POS4;
				}else{notDone = false;}
			}
		}
	}
}

void tetrisMap::rotateRightLShapeClockwiseFourthPosition()
{
	for(int i = 0; i <= m_height; ++i)
	{
		for(int i2 = 0; i2 <= m_width; ++i2)
		{
			if(m_mapArray[i][i2] && notDone)
			{
				if(!m_staticArray[i][i2-1] && !m_staticArray[i-1][i2-1])
				{
					m_mapArray[i][i2] = false; m_mapArray[i+1][i2-2] = false;
					m_mapArray[i][i2-1] = true; m_mapArray[i-1][i2-1] = true;
					//color array
					m_colorArray[i][i2] = BASE_COLOR; m_colorArray[i+1][i2-2] = BASE_COLOR;
					m_colorArray[i][i2-1] = PURPLE_COLOR; m_colorArray[i-1][i2-1] = PURPLE_COLOR;
					notDone = false;
					m_curShapePos = POS1;
				}else{notDone = false;}
			}
		}
	}
}

void tetrisMap::rotateLeftLShapeClockwiseFirstPosition()
{
	for(int i = 0; i <= m_height; ++i)
	{
		for(int i2 = 0; i2 <= m_width; ++i2)
		{
			if(m_mapArray[i][i2] && notDone)
			{
				if(i2+1 <= m_width && i2-1 >= 0 && !m_staticArray[i][i2-1] &&
					!m_staticArray[i+1][i2-1] && !m_staticArray[i+1][i2+1])
				{
					m_mapArray[i][i2] = false; m_mapArray[i+2][i2] = false; m_mapArray[i+2][i2-1] = false;
					m_mapArray[i][i2-1] = true; m_mapArray[i+1][i2-1] = true; m_mapArray[i+1][i2+1] = true;
					//color array
					m_colorArray[i][i2] = BASE_COLOR; m_colorArray[i+2][i2] = BASE_COLOR; m_colorArray[i+2][i2-1] = BASE_COLOR;
					m_colorArray[i][i2-1] = GREEN_COLOR; m_colorArray[i+1][i2-1] = GREEN_COLOR; m_colorArray[i+1][i2+1] = GREEN_COLOR;
					notDone = false;
					m_curShapePos = POS2;
				}else{notDone = false;}
			}
		}
	}
}

void tetrisMap::rotateLeftLShapeClockwiseSecondPosition()
{
	for(int i = 0; i <= m_height; ++i)
	{
		for(int i2 = 0; i2 <= m_width; ++i2)
		{
			if(m_mapArray[i][i2] && notDone)
			{
				if(i+2 <= m_height && !m_staticArray[i+2][i2+1] && !m_staticArray[i][i2+2] && !m_staticArray[i][i2+1])
				{
					m_mapArray[i][i2] = false; m_mapArray[i+1][i2] = false; m_mapArray[i+1][i2+2] = false;
					m_mapArray[i][i2+1] = true; m_mapArray[i][i2+2] = true; m_mapArray[i+2][i2+1] = true;
					//color array
					m_colorArray[i][i2] = BASE_COLOR; m_colorArray[i+1][i2] = BASE_COLOR; m_colorArray[i+1][i2+2] = BASE_COLOR;
					m_colorArray[i][i2+1] = GREEN_COLOR; m_colorArray[i][i2+2] = GREEN_COLOR; m_colorArray[i+2][i2+1] = GREEN_COLOR;
					notDone = false;
					m_curShapePos = POS3;
				}else{notDone = false;}
			}
		}
	}
}

void tetrisMap::rotateLeftLShapeClockwiseThirdPosition()
{
	for(int i = 0; i <= m_height; ++i)
	{
		for(int i2 = 0; i2 <= m_width; ++i2)
		{
			if(m_mapArray[i][i2] && notDone)
			{
				if(i2-1 >= 0 && !m_staticArray[i+1][i2-1] && !m_staticArray[i+1][i2+1] && !m_staticArray[i+2][i2+1])
				{
					m_mapArray[i][i2] = false; m_mapArray[i][i2+1] = false; m_mapArray[i+2][i2] = false;
					m_mapArray[i+1][i2-1] = true; m_mapArray[i+1][i2+1] = true; m_mapArray[i+2][i2+1] = true;
					//color array
					m_colorArray[i][i2] = BASE_COLOR; m_colorArray[i][i2+1] = BASE_COLOR; m_colorArray[i+2][i2] = BASE_COLOR;
					m_colorArray[i+1][i2-1] = GREEN_COLOR; m_colorArray[i+1][i2+1] = GREEN_COLOR; m_colorArray[i+2][i2+1] = GREEN_COLOR;
					notDone = false;
					m_curShapePos = POS4;
				}else{notDone = false;}
			}
		}
	}
}

void tetrisMap::rotateLeftLShapeClockwiseFourthPosition()
{
	for(int i = 0; i <= m_height; ++i)
	{
		for(int i2 = 0; i2 <= m_width; ++i2)
		{
			if(m_mapArray[i][i2] && notDone)
			{
				if(!m_staticArray[i-1][i2+2] && !m_staticArray[i+1][i2+1])
				{
					m_mapArray[i][i2] = false; m_mapArray[i][i2+1] = false;
					m_mapArray[i-1][i2+2] = true; m_mapArray[i+1][i2+1] = true;
					//color array 
					m_colorArray[i][i2] = BASE_COLOR; m_colorArray[i][i2+1] = BASE_COLOR;
					m_colorArray[i-1][i2+2] = GREEN_COLOR; m_colorArray[i+1][i2+1] = GREEN_COLOR;
					notDone = false;
					m_curShapePos = POS1;
				}else{notDone = false;}
			}
		}
	}
}

void tetrisMap::rotateSShapeToHorizontalPosition()
{
	for(int i = 0; i <= m_height; ++i)
	{
		for(int i2 = 0; i2 <= m_width; ++i2)
		{
			if(m_mapArray[i][i2] && notDone)
			{
				if(i+2 <= m_height && !m_staticArray[i+2][i2+1] && !m_staticArray[i+1][i2+1])
				{
					m_mapArray[i+1][i2-1] = false; m_mapArray[i][i2+1] = false;
					m_mapArray[i+1][i2+1] = true; m_mapArray[i+2][i2+1] = true;
					//color array
					m_colorArray[i+1][i2-1] = BASE_COLOR; m_colorArray[i][i2+1] = BASE_COLOR;
					m_colorArray[i+1][i2+1] = TEAL_COLOR; m_colorArray[i+2][i2+1] = TEAL_COLOR;
					notDone = false;
					m_curShapePos = POS2;
				}else{notDone = false;}
			}
		}
	}
}

void tetrisMap::rotateSShapeToVerticalPosition()
{
	for(int i = 0; i <= m_height; ++i)
	{
		for(int i2 = 0; i2 <= m_width; ++i2)
		{
			if(m_mapArray[i][i2] && notDone)
			{
				if(i2+2 <= m_width && !m_staticArray[i][i2+2] && !m_staticArray[i][i2+1])
				{
					m_mapArray[i][i2] = false; m_mapArray[i+2][i2+1] = false;
					m_mapArray[i][i2+1] = true; m_mapArray[i][i2+2] = true;
					//color array
					m_colorArray[i][i2] = BASE_COLOR; m_colorArray[i+2][i2+1] = BASE_COLOR;
					m_colorArray[i][i2+1] = TEAL_COLOR; m_colorArray[i][i2+2] = TEAL_COLOR;
					notDone = false;
					m_curShapePos = POS1;
				}else{notDone = false;}
			}
		}
	}
}

void tetrisMap::rotateZShapeToHorizontalPosition()
{
	for(int i = 0; i <= m_height; ++i)
	{
		for(int i2 = 0; i2 <= m_width; ++i2)
		{
			if(m_mapArray[i][i2] && notDone)
			{
				if(i+2 <= m_height && !m_staticArray[i+2][i2] && !m_staticArray[i+1][i2])
				{
					m_mapArray[i][i2] = false; m_mapArray[i+1][i2+2] = false;
					m_mapArray[i+1][i2] = true; m_mapArray[i+2][i2] = true;
					//color array
					m_colorArray[i][i2] = BASE_COLOR; m_colorArray[i+1][i2+2] = BASE_COLOR;
					m_colorArray[i+1][i2] = BROWN_COLOR; m_colorArray[i+2][i2] = BROWN_COLOR;
					notDone = false;
					m_curShapePos = POS2;
				}else{notDone = false;}
			}
		}
	}
}

void tetrisMap::rotateZShapeToVerticalPosition()
{
	for(int i = 0; i <= m_height; ++i)
	{
		for(int i2 = 0; i2 <= m_width; ++i2)
		{
			if(m_mapArray[i][i2] && notDone)
			{
				if(i2+1 <= m_width && !m_staticArray[i+2][i2+1] && !m_staticArray[i+2][i2])
				{
					m_mapArray[i][i2] = false; m_mapArray[i+2][i2-1] = false;
					m_mapArray[i+2][i2] = true; m_mapArray[i+2][i2+1] = true;
					//color array
					m_colorArray[i][i2] = BASE_COLOR; m_colorArray[i+2][i2-1] = BASE_COLOR;
					m_colorArray[i+2][i2] = BROWN_COLOR; m_colorArray[i+2][i2+1] = BROWN_COLOR;
					notDone = false;
					m_curShapePos = POS1;
				}else{notDone = false;}
			}
		}
	}
}

void tetrisMap::createSquare()
{
	m_mapArray[0][5] = true;
	m_mapArray[0][6] = true;
	m_mapArray[1][5] = true;
	m_mapArray[1][6] = true;
	//set the color up
	m_colorArray[0][5] = YELLOW_COLOR;
	m_colorArray[0][6] = YELLOW_COLOR;
	m_colorArray[1][5] = YELLOW_COLOR;
	m_colorArray[1][6] = YELLOW_COLOR;
	m_curShapePos = POS1;
}

void tetrisMap::createStraightLine()
{
	m_mapArray[0][5] = true;
	m_mapArray[1][5] = true;
	m_mapArray[2][5] = true;
	m_mapArray[3][5] = true;
	//set the color up
	m_colorArray[0][5] = BLUE_COLOR;
	m_colorArray[1][5] = BLUE_COLOR;
	m_colorArray[2][5] = BLUE_COLOR;
	m_colorArray[3][5] = BLUE_COLOR;
	m_curShapePos = POS1;
}

void tetrisMap::createTShape()
{
	m_mapArray[0][5] = true;
	m_mapArray[1][4] = true;
	m_mapArray[1][5] = true;
	m_mapArray[1][6] = true;
	//set up the color
	m_colorArray[0][5] = RED_COLOR;
	m_colorArray[1][4] = RED_COLOR;
	m_colorArray[1][5] = RED_COLOR;
	m_colorArray[1][6] = RED_COLOR;
	m_curShapePos = POS1;
}

void tetrisMap::createRightLShape()
{
	m_mapArray[0][5] = true;
	m_mapArray[1][5] = true;
	m_mapArray[2][5] = true;
	m_mapArray[2][6] = true;
	//set up the color
	m_colorArray[0][5] = PURPLE_COLOR;
	m_colorArray[1][5] = PURPLE_COLOR;
	m_colorArray[2][5] = PURPLE_COLOR;
	m_colorArray[2][6] = PURPLE_COLOR;
	m_curShapePos = POS1;
}

void tetrisMap::createLeftLShape()
{
	m_mapArray[0][5] = true;
	m_mapArray[1][5] = true;
	m_mapArray[2][5] = true;
	m_mapArray[2][4] = true;
	//set up the color
	m_colorArray[0][5] = GREEN_COLOR;
	m_colorArray[1][5] = GREEN_COLOR;
	m_colorArray[2][5] = GREEN_COLOR;
	m_colorArray[2][4] = GREEN_COLOR;
	m_curShapePos = POS1;
}

void tetrisMap::createSShape()
{
	m_mapArray[0][5] = true;
	m_mapArray[0][6] = true;
	m_mapArray[1][4] = true;
	m_mapArray[1][5] = true;
	//set up the color
	m_colorArray[0][5] = TEAL_COLOR;
	m_colorArray[0][6] = TEAL_COLOR;
	m_colorArray[1][4] = TEAL_COLOR;
	m_colorArray[1][5] = TEAL_COLOR;
	m_curShapePos = POS1;
}

void tetrisMap::createZShape()
{
	m_mapArray[0][4] = true;
	m_mapArray[0][5] = true;
	m_mapArray[1][5] = true;
	m_mapArray[1][6] = true;
	//set up the color
	m_colorArray[0][4] = BROWN_COLOR;
	m_colorArray[0][5] = BROWN_COLOR;
	m_colorArray[1][5] = BROWN_COLOR;
	m_colorArray[1][6] = BROWN_COLOR;
	m_curShapePos = POS1;
}

void tetrisMap::setNextSquarePiece()
{
		m_nextArray[0][7] = true;
		m_nextArray[0][8] = true;
		m_nextArray[1][7] = true;
		m_nextArray[1][8] = true;
		m_curShapePos = POS1;
}

void tetrisMap::setNextStraightLinePiece()
{
	m_nextArray[0][7] = true;
	m_nextArray[1][7] = true;
	m_nextArray[2][7] = true;
	m_nextArray[3][7] = true;
	m_curShapePos = POS1;
}

void tetrisMap::setNextTShapePiece()
{
	m_nextArray[0][7] = true;
	m_nextArray[1][6] = true;
	m_nextArray[1][7] = true;
	m_nextArray[1][8] = true;
	m_curShapePos = POS1;
}

void tetrisMap::setNextRightLShapePiece()
{
	m_nextArray[0][7] = true;
	m_nextArray[1][7] = true;
	m_nextArray[2][7] = true;
	m_nextArray[2][8] = true;
	m_curShapePos = POS1;
}

void tetrisMap::setNextLeftLShapePiece()
{
	m_nextArray[0][7] = true;
	m_nextArray[1][7] = true;
	m_nextArray[2][7] = true;
	m_nextArray[2][6] = true;
	m_curShapePos = POS1;
}

void tetrisMap::setNextSShapePiece()
{
		m_nextArray[0][7] = true;
		m_nextArray[0][8] = true;
		m_nextArray[1][6] = true;
		m_nextArray[1][7] = true;
		m_curShapePos = POS1;
}

void tetrisMap::setNextZShapePiece()
{
	m_nextArray[0][6] = true;
	m_nextArray[0][7] = true;
	m_nextArray[1][7] = true;
	m_nextArray[1][8] = true;
	m_curShapePos = POS1;
}

tetrisMap::~tetrisMap()
{
	//this doesnt do anything now does it?

	//delete [] m_mapArray;
	//delete [] m_staticArray;
	//delete [] m_pieceArray;
}
void tetrisMap::drawProjected(int eye[4], int eye2[4])
{
	int a;
	int b;
	int c;
	bool foundBottom = false;
	int count = 0;

	switch(m_curShapeID)
		{
		case 0:
			SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),YELLOW_COLOR); 
			break;
		case 1:
			SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),BLUE_COLOR); 
			break;
		case 2:
			SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),RED_COLOR);
			break;
		case 3:
			SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),PURPLE_COLOR);
			break;
		case 4:
			SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),GREEN_COLOR);
			break;
		case 5:
			SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),TEAL_COLOR);
			break;
		case 6:
			SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),BROWN_COLOR);
			break;
		}

	while(!foundBottom)
	{
		if(checkDown(eye, eye2))
		{			
			while(count <= 3)
			{
				c = eye[count];
				c++;
				eye[count] = c;
				++count;
			}
			count = 0;
		}
		if(!checkDown(eye,eye2))
		{
			foundBottom = true;
		}
	}
	count = 0;
	while(count <= 3)
	{
		a = eye[count];
		b = eye2[count];
		if(hitBottom)
		{
			a++;
		}
		if(singleDown)
		{
			a++;
		}
		COORD p = {b + m_hposition,a};
		SetConsoleCursorPosition(
			GetStdHandle(STD_OUTPUT_HANDLE), p);
		printf("O");
		++count;
		
	}
	singleDown = false;
}
bool tetrisMap::checkDown(int eye[4], int eye2[4])
{
	bool canMove = true;
	int count = 0;
	while(count <= 3)
	{
		for(int i2 = 0; i2 <= m_width; ++i2)
		{
			if(m_staticArray[14][i2] && !m_staticArray[13][i2])
			{
				if(eye[count] == 13 && eye2[count] == i2)
				{
					singleDown = true;
					hitBottom = false;
					return false;
				}
			}
		}
		if(eye[count] == m_height)
		{
			hitBottom = true;
			return false;
		}
		else
		{
			for(int i = 0; i <= m_height; ++i)
			{
				for(int i2 = 0; i2 <= m_width; ++i2)
				{
					if(i != 14)
					{
						if(m_staticArray[i+1][i2])
						{					
							if(eye[count] == i+1 && eye2[count] == i2)
							{
//								singleDown = false;
								hitBottom = false;
								return false;
							}
						}
					}
				}
			}
		}
		++count;
	}
	return canMove;
}
void tetrisMap::slamPiece()
{
	    bool canMove = false;
        //do collision detection here!
        for(int i = 0; i <= m_height; ++i)
        {
                for(int i2 = 0; i2 <= m_width; ++i2)
                {
                        if((m_mapArray[i][i2]) && (i == (m_height)))
                        {
								canMove = false;
                        }
                        else if(m_mapArray[i][i2] && m_staticArray[i+1][i2])
                        {
								canMove = false;
                        }
                        else
                        {
                                canMove = true;
                        }
                }
        }
        //if we can move down we do it, but we do it from the bottom up to prevent overlapping a shape
        while(canMove)
        {
                for(int i = m_height; i >= 0; --i)
                {
                        for(int i2 = 0; i2 <= m_width; ++i2)
                        {
                                if(m_mapArray[i][i2])
                                {
                                        m_mapArray[i+1][i2] = true;
                                        m_mapArray[i][i2] = false;
                                        m_colorArray[i+1][i2] = m_colorArray[i][i2];
                                        m_colorArray[i][i2] = BASE_COLOR;
                                }
                        }
				}
        //do collision detection here!
				for(int i = 0; i <= m_height; ++i)
				{
						for(int i2 = 0; i2 <= m_width; ++i2)
						{
								if((m_mapArray[i][i2]) && (i == (m_height)))
								{
									//printf("1\n");
									canMove = false;
								}
								else if(m_mapArray[i][i2] && m_staticArray[i+1][i2])
								{
									//printf("2\n");
									canMove = false;
								}
						}
				}
        }
		addToStatic();
		clearMap();
		createPiece();

}